<?php

require_once("config.php");
require_once("utils.php");
require_once('MySugarApplication.php');
session_start();

class Component {
	var $proxy;
    var $sess;
	var $moduleName;
	var $requestColumns;
	var $defaultColumns;
	var $recordCount;
	var $orderBy;
	var $quote;

	var $startIndex;
	var $numberOfRows;
	var $recordCountOnly;
	var $keysOnly;
	var $tableName;
	var $customQuery;
	var $includeDeleted;

	var $restUrl;
		
        function __construct($moduleName, $tableName, $sugarcrm_rest_url, $defaultColumns){
			
        	$this->restUrl = $sugarcrm_rest_url;
			$this->sess = $_SESSION["sugar_session_id"];
			$this->moduleName=$moduleName;
			$this->tableName=$tableName;
			$this->columsList = array();
			$this->recordCount = 0;
			$this->includeDeleted = false;
			$this->orderBy = "";
			$this->customQuery = "";

			$this->quote = '"';
			$this->recordCountOnly = isset($_REQUEST['recordCount']) ? $_REQUEST['recordCount'] : "N";
			$this->keysOnly = isset($_REQUEST['keysOnly']) ? $_REQUEST['keysOnly'] : "N";
			
			$this->defaultColumns = $defaultColumns;
			
			# add these columns for all requests.
			$this->defaultColumns[] = "id";
            $this->defaultColumns[] = "date_modified";
            $this->defaultColumns[] = "deleted";
        }

	function processKeySearchColumns() {

                ## if search parameter are passed then process them
                $keyColumnsList = getParamsList("keyColumn");
                $keyValuesList = getParamsList("keyValue");
                $valuesCount = count($keyValuesList);

                $keySearch = "";
                foreach ($keyColumnsList as $keyColumn) {

                        $columnPosition = array_search($keyColumn, $keyColumnsList);
                        if ($columnPosition <=  $valuesCount-1) {
                                $value = $keyValuesList[$columnPosition];
                                if (strpos($keyColumn, ".") == false) {
                                        $keyColumn = $this->tableName.".".$keyColumn;
                                }

                                $operator = " = ";
                                $value = str_replace('"',"",$value);
                                if (strpos($value, "?") !== false || strpos($value, "*") !== false) {
                                        $operator = " like ";
                                        $value = str_replace("?", "_", $value);
                                        $value = str_replace("*", "%", $value);
                                }
                                if ($keySearch == "")
                                        $keySearch = " ".$keyColumn.$operator." '".$value."' ";
                                else
                                        $keySearch .= " AND ".$keyColumn.$operator." '".$value."' ";

                        }

                }

                if ($this->customQuery != "" && $keySearch != "")
                        $this->customQuery .= " AND ".$keySearch;
                else if ($keySearch != "")
                        $this->customQuery = $keySearch;

#                foreach ($columnMappings as $column => $value) {
#                        $query = str_replace($column, $columnMappings[$column], $query);
#                }


        }

	function processSearchColumns() {

		## if search parameter are passed then process them
		$searchColumnsList = getParamsList("searchColumn");
        $searchValuesList = getParamsList("searchValue");
        $valuesCount = count($searchValuesList);

        $search = "";
        foreach ($searchColumnsList as $searchColumn) {

        	$columnPosition = array_search($searchColumn, $searchColumnsList);
            if ($columnPosition <=  $valuesCount-1) {
            	$value = $searchValuesList[$columnPosition];
                if (strpos($searchColumn, ".") == false) {
                	$searchColumn = $this->tableName.".".$searchColumn;
                }

                $operator = " = ";
                $value = str_replace('"',"",$value);
                if (strpos($value, "?") !== false || strpos($value, "*") !== false) {
                	$operator = " like ";
                    $value = str_replace("?", "_", $value);
                    $value = str_replace("*", "%", $value);
                }
                if ($search == "")
                	$search = " ".$searchColumn.$operator." '".$value."' ";
                else
                	$search .= " OR ".$searchColumn.$operator." '".$value."' ";

                }

        }

		if ($this->customQuery != "" && $search != "")
                        $this->customQuery .= " AND ( ".$search." )";
                else if ($search != "")
                        $this->customQuery = "( ".$search." )";

		#foreach ($columnMappings as $column => $value) {
		#	$query = str_replace($column, $columnMappings[$column], $query);
		#}



	}

	function processQueryParameters() {

		$query = "";
		if ( $this->recordCountOnly != "Y" ) {

       		if (isset($_REQUEST["lastModifiedOn"])) {
            	$query .= " ".$this->tableName.".date_modified >= ";
                $query .= $this->quote.$_REQUEST["lastModifiedOn"].$this->quote;
                                $this->includeDeleted = true;
                }
         }


		$this->processSearchColumns();
		$this->processKeySearchColumns();

		if ($query != "" && $this->customQuery != "")
			$query .= " AND ".$this->customQuery;
		else if ($this->customQuery != "")
			$query = $this->customQuery;

		

		return $query;
	
	}

	function processPaginationParameters() {

		$startRowStr = isset($_REQUEST['startRow']) ? $_REQUEST['startRow'] : null;

		if ($startRowStr == "") {
			$this->startIndex = 1;
		} else {
			$this->startIndex = (int)$startRowStr;
		}

		$numberOfRowsStr = isset($_REQUEST['numberOfRows']) ? $_REQUEST['numberOfRows'] : null;

        if ($numberOfRowsStr == "")
        	$this->numberOfRows = 1000000000;
        else
        	$this->numberOfRows = (int)$numberOfRowsStr;

	}


	function processRequestColumns() {

    	$columnsList = getParamsList("column");

        if (count($columnsList) > 0)
        	$this->requestColumns = $columnsList;
		else
			$this->requestColumns = $this->defaultColumns;
    }
    
	## Process sorting query parameters from request sent by EVC
	## sort parameters are stored in $this->$orderBy
	function processOrderBy() {

		$sortColumnsList = getParamsList("sortByColumn");
		
		if (count($sortColumnsList) == 0) 
			return $this->tableName."."."date_modified desc";

		$columnsOrderList = getParamsList("sortByOrder");
		$columnsOrderCount = count($columnsOrderList);

		$this->orderBy = "";
		foreach ($sortColumnsList as $sortColumn) {

			$columnPosition = array_search($sortColumn, $this->defaultColumns);
			if ($columnPosition !== false) {
				$columnPosition += 1;

				if ($this->orderBy == "")
					$this->orderBy = $this->tableName.".".$sortColumn;
				else
					$this->orderBy .= ", ".$this->tableName.".".$sortColumn;
				$columnIndex = array_search($sortColumn, $sortColumnsList);
				if ($columnIndex <= $columnsOrderCount-1) {
					$order = $columnsOrderList[$columnIndex];
					$order = (strcasecmp($order, "DESC") == 0) ? "DESC" : "";
				} else {
					$order = "";
				}

				$this->orderBy .= " ".$order;
			}
		}
	}

    
	function getRecords() {
		## Process pagination parameter passed in query string
		$this->processPaginationParameters();
		 
		## process sort parameter passed in query string;
		$this->processOrderBy();
		
		## process search and key columns passed in query string
		## search columns are used for searching and key columns are used for child table lookup
		$this->processQueryParameters();
		 
		## generate list of columns that should be passed to fetch request 
		$this->processRequestColumns();

    	//$recordCount = 0;
		
		## TODO: Paginaton doesn't work. needs to be fixed.
		## fetching all rows with every request and then manually slicing array
		$call_arguments = array(
			'session' => $_SESSION["sugar_session_id"],
			'module_name' => $this->moduleName,
			'query' => $this->customQuery,
			'order_by' => $this->orderBy,
			'offset' => 0,
			'select_fields' => $this->requestColumns,
			'link_name_to_fields_array' => null,
			'max_results' => 10000000,
			'deleted' => "FALSE"
		);
		$result = $this->rest_request('get_entry_list', $call_arguments);	
		
		$returnList = array();

       	if ($result == "" || count($result) == 0)
        	return $returnList;

    	foreach ($result['entry_list'] as $record) {
        	$returnList[] = $record;
        }
      
        $this->recordCount = $result['result_count'];
        
        if ($this->numberOfRows > 0)
        	$returnList = array_slice($returnList, $this->startIndex-1, $this->numberOfRows);

    	return $returnList;
    }
    
    
	function getRecord($query) {
		## get a component record  
		$this->processRequestColumns();

    	//$recordCount = 0;
		
		## TODO: Paginaton doesn't work. needs to be fixed.
		## fetching all rows with every request and then manually slicing array
		$call_arguments = array(
			'session' => $_SESSION["sugar_session_id"],
			'module_name' => $this->moduleName,
			'query' => $query,
			'order_by' => $this->orderBy,
			'offset' => 0,
			'select_fields' => $this->requestColumns,
			'link_name_to_fields_array' => null,
			'max_results' => 1,
			'deleted' => "FALSE"
		);
		
		$result = $this->rest_request('get_entry_list', $call_arguments);	
				
		$returnList = array();

       	if ($result == "" || count($result) == 0)
        	return $returnList;
        if($result['result_count'] == 0)
        	return $returnList;

		$returnList[] = nameValuePairToSimpleArray($result['entry_list'][0]['name_value_list']);
	
    	return $returnList;
    }    
		
	function getDeletedRecords($query, $startIndex, $numberOfRows, $orderBy){
    			
    	$this->sess = $_SESSION["sugar_session_id"];
		$result = $this->proxy->get_entry_list(
       			$this->sess,
       			$this->moduleName,
       			$this->customQuery,
       			$this->orderBy,
       			$this->startIndex,
				$this->requestColumns,
       			$this->numberOfRows,
       			true
    		);
		
    		return $result;
	}
		
	
	function deleteRecord($id) {
		
		$call_arguments = array(
					'session' => $this->sess, 
    				'module' => $this->moduleName, 
    				'name_value_list' => array(
						array("name" => 'id',"value" => $id),
						array("name" => 'deleted',"value" => 1))
					);
		$response = $this->rest_request('set_entry', $call_arguments);
		
		return $response;
		
	}
		
	function nameValuePairToSimpleArray($array){
    		$my_array=array();
    		while(list($name,$value)=each($array)){
        		$my_array[$value['name']]=$value['value'];
    		}
    		return $my_array;
	} 
	
	function getQueryColumns($defaultColumns) {

                $this->columnsList = getParamsList("column");

                if (count($this->columnsList) == 0)
                        $this->columnsList = $defaultColumns;

                $this->requestedColumnsList = $this->columnsList;

                $this->columnsList[] = "id";
                $this->columnsList[] = "date_modified";
                $this->columnsList[] = "deleted";


                $queryColumns = "";
                foreach ($this->columnsList as $column) {
                        if ($queryColumns == "")
                        	$queryColumns = $this->tableName.".".$column;
                        else
                                $queryColumns .= ", ".$this->tableName.".".$column;

//			if ($column == "date_modified") {
//				$searchStr = $this->tableName.".".$column;
//				$replaceStr = "convert_tz(".$this->tableName.".".$column.", '+00:00','-04:00') ".$column;
//			
//				$queryColumns = str_replace($searchStr, $replaceStr, $queryColumns); 
//			}

                }

                return $queryColumns;
        }
        
		function getRecordsCount() {
			$count = empty($this->recordCount) ? 0 : $this->recordCount;
			return $count;
		}
        	
 	/**
	* Function:	rest_request()
	* Parameters: 	$call_name	= (string) the API call name
	*				$call_arguments	= (array) the arguments for the API call
	* Description:	Makes an API call given a call name and arguments
	* Returns:	An array with the API call response data
	*/
 	function rest_request($call_name, $call_arguments) {

		$ch = curl_init(); 
		
		$post_data = 'method='.$call_name.'&input_type=JSON&response_type=JSON';
		$jsonEncodedData = json_encode($call_arguments);
		$post_data = $post_data . "&rest_data=" . $jsonEncodedData;
	
        curl_setopt($ch, CURLOPT_URL, $this->restUrl); 
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

		curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        $output = curl_exec($ch); 
		
		$response_data = json_decode($output,true);
			
		return $response_data;
	}
		
		
}
	
?>
